#pragma once

#include <iostream>
#include <string>
#include <list>
#include <memory>
#include <algorithm>
#include <sys/types.h>
#include <sys/socket.h>

#include "InetAddr.hpp"
#include "Log.hpp"
#include "Mutex.hpp"

using namespace LogMudule;
using namespace LockModule;

class UserBase
{
public:
    UserBase() = default;
    ~UserBase() = default;

    virtual void SendTo(int socketfd, const std::string &message) = 0;
    virtual std::string Id() = 0;
    virtual bool operator==(const InetAddr &addr) = 0;
};

class User : public UserBase
{
public:
    User(const InetAddr &id) : _id(id)
    {
    }
    // 对当前用户进行转发
    void SendTo(int socketfd, const std::string &message) override
    {
        LOG(LogLevel::ERROR) << "向用户转发"<<_id.GetIp();
        int n = sendto(socketfd, message.c_str(), message.size(), 0, _id.GetAddr(), _id.Addr_size());
        if (n < 0)
        {
            LOG(LogLevel::ERROR) << "server sendto err...";
        }
    }
    std::string Id() override
    {
        std::string ret = _id.GetIp();
        ret += (":" + _id.GetProt());
        return ret;
    }
    bool operator==(const InetAddr &id) override
    {
        return _id == id;
    }

    ~User() = default;

private:
    InetAddr _id;
};

class UserManager
{
private:
    bool FindUser(const InetAddr &id)
    {
        for (auto e : user_list)
        {
            if (*e == id)
                return false;
        }

        return true;
    }

public:
    UserManager() = default;
    ~UserManager() = default;

    void AddUser(const InetAddr &id)
    {
        LockGuard l(mt);
        if (FindUser(id))
        {
            user_list.push_back(std::make_shared<User>(id));
            LOG(LogLevel::DEBUG)<<"用户"<<id.GetIp()<<"添加成功";
        }
    }

    void DelUser(const InetAddr &id)
    {
        LockGuard l(mt);

        auto pos = std::remove_if(user_list.begin(),user_list.end(),[&id](std::shared_ptr<UserBase> &user)
        {return *user == id;});

        if(pos == user_list.end())
        {
           LOG(LogLevel::DEBUG)<<"当前用户不存在"; 
        }
           
        LOG(LogLevel::DEBUG)<<"用户退出成功";
        user_list.erase(pos,user_list.end());
     
    }

    void Router(const int & socketfb, const std::string &message)
    {
        LockGuard l(mt);
        LOG(LogLevel::DEBUG)<<"开始路由了";
        for(auto e : user_list)
        {
            LOG(LogLevel::DEBUG)<<"向"<<"发送信息";
            e->SendTo(socketfb,message);
        }
    }

private:
    std::list<std::shared_ptr<UserBase>> user_list;
    Mutex mt;
};
